/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bakenote.xml;

import bakenote.BakeNote;
import bakenote.core.Formula;
import bakenote.core.Ingredient;
import bakenote.core.Procedure;
import bakenote.core.Recipe;
import org.apache.pivot.collections.List;
import org.apache.pivot.xml.Element;
import org.apache.pivot.xml.TextNode;
import org.apache.pivot.xml.XMLSerializer;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.*;

/**
 * @author lello
 *         <p/>
 *         The writer should write the recipe in this format
 *         <p/>
 *         <recipe title="Ricetta di prova" author="lello" source="nessuna" tag="" kind="pane">
 *         <uuid>...............<uuid>
 *         <formula title="Biga">
 *         <ingredient name="farina" amount="150" units="g" />
 *         <ingredient name="acqua "amount="150" units="g" />
 *         <ingredient name="lievito" amount="150" units="g" />
 *         </formula>
 *         <formula title="Impasto finale">
 *         <ingredient name="farina" amount="150" units="g" />
 *         <ingredient name="acqua "amount="150" units="g" />
 *         <ingredient name="lievito" amount="150" units="g" />
 *         </formula>
 *         <instructions>
 *         Mescolare tutto
 *         </instructions>
 *         </recipe>
 */
public class RecipeXMLWriter {

    private static XMLSerializer xmlSerializer = new XMLSerializer();

    private RecipeXMLWriter() {
    }

    private static Element recipeXML(Recipe r) {

        Element recipeElement = new Element("recipe");
        recipeElement.put("title", r.getName());
        if (r.getAuthor() != null) recipeElement.put("author", r.getAuthor());
        if (r.getSource() != null) recipeElement.put("source", r.getSource());
        if (r.getType() != null) recipeElement.put("kind", r.getType());
        if (r.getTag() != null) {
            Element tagElement = new Element("tag");
            tagElement.add(new TextNode(r.getTag()));
            recipeElement.add(tagElement);
        }
        recipeElement.put("rating", ((Integer) r.getRating()).toString());
        Element uuidElement = new Element("uuid");
        uuidElement.add(new TextNode(r.getUUID()));
        recipeElement.add(uuidElement);

        for (Formula f : r.getFormulaList()) {
            Element formulaElement = new Element("formula");
            formulaElement.put("name", f.getName());
            for (Ingredient in : f.getIngredients()) {
                Element ingredientElement = new Element("ingredient");
                ingredientElement.put("name", in.getName());
                ingredientElement.put("amount", in.getAmount().toString());
                ingredientElement.put("unit", in.getUnit());
                formulaElement.add(ingredientElement);
            }
            recipeElement.add(formulaElement);
        }

        String recipeDirName = BakeNote.getFileStorageDirectory() + File.separator + r.getUUID();
        String noteFileName = recipeDirName + File.separator + "notes.txt";
        String procedureFileName = recipeDirName + File.separator + "procedure.xml";
        System.out.println("file name " + procedureFileName);
        File noteFile = new File(noteFileName);
        File procedureFile = new File(procedureFileName);

        Procedure procedure = ProcedureXMLReader.readXML(procedureFile);

        Element procedureElement = new Element("procedure");
        for (int i = 0; i < procedure.getElementalProcedureList().getLength(); i++) {
            Element stepElement = new Element("step");
            Element timeElement = new Element("time");
            TextNode textNode = new TextNode(procedure.getStep(i).getDuration().toString());
            timeElement.add(textNode);
            Element descriptionElement = new Element("description");
            textNode = new TextNode(procedure.getStep(i).getDescription());
            descriptionElement.add(textNode);
            stepElement.add(descriptionElement);
            stepElement.add(timeElement);
            procedureElement.add(stepElement);
        }
        recipeElement.add(procedureElement);

        StringBuilder sb = new StringBuilder();
        try {
            FileReader fileReader = new FileReader(noteFile);
            BufferedReader bufferedReader = new BufferedReader(fileReader);
            String s = "";
            while ((s = bufferedReader.readLine()) != null) {
                sb.append(s);
            }
        } catch (FileNotFoundException e) {
            System.out.println("FileNotFound: cannot find notes file");
            //e.printStackTrace();
        } catch (IOException e) {
            System.out.println("IOException: cannot read notes file");
            //e.printStackTrace();
        }

        // Add the notes
        Element noteElement = new Element("notes");
        TextNode noteText = new TextNode(sb.toString());
        noteElement.add(noteText);
        recipeElement.add(noteElement);

        return recipeElement;
    }

    public static void writeXML(List<Recipe> recipeList, File xmlFile) throws Exception {

        Element recipeBook = new Element("recipebook");
        for (Recipe r : recipeList) {
            recipeBook.add(recipeXML(r));
        }

        // Write the recipeBook to a stringWriter for later indentation
        StringWriter stringWriter = new StringWriter();
        xmlSerializer.writeObject(recipeBook, stringWriter);

        // Apply indentation to the stringWriter
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");

        StringWriter indentedStringWriter = new StringWriter();
        transformer.transform(new StreamSource(new StringReader(stringWriter.toString())), new StreamResult(indentedStringWriter));
        // Save the xml element to a file
        FileWriter fw = new FileWriter(xmlFile, true);
        fw.write(indentedStringWriter.toString());
        fw.flush();
        fw.close();

        //System.out.println("xml done");
    }
}
